Spring Boot-এর মাধ্যমে একটি অ্যাপ্লিকেশনে একাধিক ডাটাবেস সংযোগ (Multiple DataSource) কনফিগার করা যেতে পারে। এই ধরনের কনফিগারেশন তখন ব্যবহৃত হয় যখন আপনি একটি অ্যাপ্লিকেশনে একাধিক ডাটাবেসের সাথে কাজ করতে চান, যেমন একটি রিলেশনাল ডাটাবেস (MySQL/PostgreSQL) এবং একটি NoSQL ডাটাবেস (MongoDB) বা একাধিক রিলেশনাল ডাটাবেস।
Spring Boot এ Multiple DataSource কনফিগার করার জন্য কিছু গুরুত্বপূর্ণ পদক্ষেপ রয়েছে, যেমন:
- Multiple DataSource কনফিগারেশন তৈরি করা
- DataSource Bean তৈরি করা
- EntityManagerFactory কনফিগার করা
- Transaction Manager কনফিগার করা
- Repository কনফিগারেশন
এখানে আমরা দুটি ডাটাবেস (যেমন MySQL এবং PostgreSQL) কনফিগার করার উদাহরণ দেখবো।
১. Multiple DataSource কনফিগারেশন তৈরি করা
প্রথমে, application.properties বা application.yml ফাইলে দুটি ডাটাবেসের কনফিগারেশন যুক্ত করতে হবে।
application.properties-এ কনফিগারেশন:
# Primary DataSource (MySQL)
spring.datasource.primary.url=jdbc:mysql://localhost:3306/primarydb
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.primary.jpa.hibernate.ddl-auto=update
spring.datasource.primary.jpa.show-sql=true
# Secondary DataSource (PostgreSQL)
spring.datasource.secondary.url=jdbc:postgresql://localhost:5432/secondarydb
spring.datasource.secondary.username=postgres
spring.datasource.secondary.password=postgres
spring.datasource.secondary.driver-class-name=org.postgresql.Driver
spring.datasource.secondary.jpa.hibernate.ddl-auto=update
spring.datasource.secondary.jpa.show-sql=true
এখানে, দুটি ডাটাবেসের জন্য আলাদা কনফিগারেশন তৈরি করা হয়েছে: primary (MySQL) এবং secondary (PostgreSQL)।
২. DataSource Bean তৈরি করা
আমরা Primary DataSource এবং Secondary DataSource কনফিগার করতে দুটি আলাদা DataSource Bean তৈরি করব। প্রতিটি ডাটাবেসের জন্য আলাদা কনফিগারেশন এবং DataSource Bean তৈরি করা হয়।
Primary DataSource Configuration:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import javax.sql.DataSource;
@Configuration
public class PrimaryDataSourceConfig {
@Value("${spring.datasource.primary.url}")
private String url;
@Value("${spring.datasource.primary.username}")
private String username;
@Value("${spring.datasource.primary.password}")
private String password;
@Value("${spring.datasource.primary.driver-class-name}")
private String driverClassName;
@Bean
@Primary
public DataSource primaryDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setDriverClassName(driverClassName);
return dataSource;
}
}
Secondary DataSource Configuration:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class SecondaryDataSourceConfig {
@Value("${spring.datasource.secondary.url}")
private String url;
@Value("${spring.datasource.secondary.username}")
private String username;
@Value("${spring.datasource.secondary.password}")
private String password;
@Value("${spring.datasource.secondary.driver-class-name}")
private String driverClassName;
@Bean
public DataSource secondaryDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setDriverClassName(driverClassName);
return dataSource;
}
}
এখানে আমরা Primary DataSource এবং Secondary DataSource দুটি আলাদা Bean তৈরি করেছি।
৩. EntityManagerFactory কনফিগার করা
প্রতিটি ডাটাবেসের জন্য আলাদা EntityManagerFactory Bean তৈরি করতে হবে। এটি JPA ব্যবহার করে ডেটা ম্যানেজমেন্টের জন্য ব্যবহৃত হয়।
Primary EntityManagerFactory:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
public class PrimaryEntityManagerFactory {
private final DataSource primaryDataSource;
public PrimaryEntityManagerFactory(DataSource primaryDataSource) {
this.primaryDataSource = primaryDataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(primaryDataSource);
factoryBean.setPackagesToScan("com.example.primary"); // Scan for entities in this package
factoryBean.setPersistenceUnitName("primaryPU");
return factoryBean;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
Secondary EntityManagerFactory:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
public class SecondaryEntityManagerFactory {
private final DataSource secondaryDataSource;
public SecondaryEntityManagerFactory(DataSource secondaryDataSource) {
this.secondaryDataSource = secondaryDataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(secondaryDataSource);
factoryBean.setPackagesToScan("com.example.secondary"); // Scan for entities in this package
factoryBean.setPersistenceUnitName("secondaryPU");
return factoryBean;
}
@Bean
public PlatformTransactionManager secondaryTransactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
এখানে, PrimaryEntityManagerFactory এবং SecondaryEntityManagerFactory দুটি আলাদা EntityManagerFactory Bean তৈরি করা হয়েছে, যেগুলি তাদের respective DataSource-এ কাজ করবে।
৪. Repository কনফিগারেশন
Spring Data JPA-তে, আমরা @EnableJpaRepositories অ্যানোটেশন ব্যবহার করে JpaRepository এর জন্য আলাদা কনফিগারেশন প্রদান করি। প্রতিটি DataSource এবং EntityManagerFactory এর জন্য আলাদা JPA Repositories কনফিগার করতে হয়।
Primary Repository Configuration:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration
@EnableJpaRepositories(basePackages = "com.example.primary", entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager")
public class PrimaryRepositoryConfig {
}
Secondary Repository Configuration:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration
@EnableJpaRepositories(basePackages = "com.example.secondary", entityManagerFactoryRef = "secondaryEntityManagerFactory", transactionManagerRef = "secondaryTransactionManager")
public class SecondaryRepositoryConfig {
}
এখানে, প্রতিটি রেপোজিটরি কনফিগারেশন পৃথক EntityManager এবং TransactionManager ব্যবহার করে ডাটাবেসে ডেটা অপারেশন করবে।
৫. Usage in Service Layer
এখন আপনি Primary এবং Secondary ডাটাবেস থেকে ডেটা এক্সেস করতে Service Layer ব্যবহার করতে পারেন।
উদাহরণ: Service Layer
@Service
public class EmployeeService {
@Autowired
private PrimaryEmployeeRepository primaryEmployeeRepository;
@Autowired
private SecondaryEmployeeRepository secondaryEmployeeRepository;
public void saveEmployeeInPrimaryDb(Employee employee) {
primaryEmployeeRepository.save(employee);
}
public void saveEmployeeInSecondaryDb(Employee employee) {
secondaryEmployeeRepository.save(employee);
}
}
সারাংশ
Spring Boot Multiple DataSource Configuration আপনাকে একটি অ্যাপ্লিকেশনে একাধিক ডাটাবেসের সাথে কাজ করতে সক্ষম করে। আপনি Primary DataSource এবং Secondary DataSource কনফিগার করে তাদের জন্য আলাদা EntityManagerFactory, TransactionManager, এবং JpaRepository কনফিগারেশন করতে পারেন। এইভাবে, আপনি Spring Boot অ্যাপ্লিকেশনগুলোতে একাধিক ডাটাবেসের সাপোর্ট যোগ করতে পারেন এবং সহজে তাদের মধ্যে ডেটা অপারেশন পরিচালনা করতে পারেন।